package com.xgimi.locales.ui

import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.ui.DialogWrapper
import com.xgimi.locales.bean.InputConfig
import com.xgimi.locales.bean.SheetBean
import com.xgimi.locales.ext.*
import com.xgimi.locales.utils.Constant
import com.xgimi.locales.utils.ExcelUtil
import com.xgimi.locales.utils.XmlParserUtil
import java.awt.Component
import java.awt.Dimension
import java.io.File
import javax.swing.*

/**
 * 导入界面
 * []Excel文件路径
 * -------------------------------------------
 * 选中翻译文件后，根据excel的内容，显示对应的选项.
 * -------------------------------------------
 * []选择需要导入的语言类型 (en-rGB 英语(英国),en-rUS 英语(美国),uk 乌克兰语...)
 * []选择默认语言语种(默认value或en...)
 * []是否自动补全缺失的文件夹和文件(启动/关闭)
 * []是否开启智能修复(启动/关闭)
 * []选择需要导入的模块()
 */
class InputConfigDialog(private val anActionEvent: AnActionEvent, private val inputConfig: InputConfig): DialogWrapper(true) {

    companion object {
        fun show(anActionEvent: AnActionEvent, inputConfig:InputConfig) {
            InputConfigDialog(anActionEvent, inputConfig).apply {
                pack()
                showAndGet()
            }
        }
    }

    init {
        init()
        title = "excel导入xml 参数配置"
        setSize(500, 100)
    }

    private var rootBox: Box? = null

    override fun createCenterPanel(): JComponent = Box.createVerticalBox().apply {
        rootBox = this
        add(createFilePathBox())
    }

    private var excelPath: JTextField? = null
    /**
     * 选择Excel文件
     */
    private fun createFilePathBox(): JComponent =
        Box.createHorizontalBox().apply {
            add(JLabel("Excel文件路径:").labelSize())
            add(Box.createHorizontalGlue())
            add(Box.createHorizontalBox().apply {
                excelPath = JTextField()
                excelPath?.isEnabled = false
                add(excelPath.apply { minimumSize = Dimension(300, 10) })
                add(Box.createHorizontalStrut(10))
                add(JButton("选择文件/保存路径").apply {
                    addActionListener {
                        //选择文件
                        val fileChooser = JFileChooser()
                        fileChooser.fileSelectionMode = JFileChooser.FILES_ONLY
                        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                            val selectedFile: File = fileChooser.selectedFile
                            if (selectedFile.exists()) {
                                excelPath!!.text = selectedFile.absolutePath
                                // excel 路径
                                inputConfig.sheetNames.clear()
                                inputConfig.excelPath = selectedFile.absolutePath
                                println("excel file Path:${inputConfig.excelPath}")
                                // FIXME:避免删除第一行的选择文件，后续需要改改代码
                                var firstItem = true
                                rootBox?.components?.forEach {
                                    if (!firstItem) {
                                        rootBox?.remove(it)
                                    }
                                    firstItem = false
                                }
                                parserExcel()
                            }
                        }
                    }
                })
            })
        }

    /**
     * 解析excel表格
     */
    private fun parserExcel() {
        val file = File(inputConfig.excelPath)
        if (!file.exists()) {
            "${inputConfig.excelPath} Excel文件不存在".showError()
            return
        }
        /*
        1. 将excel中所有的 sheet tab 的名称 读取出来. sheet tab name 对应的是项目中的module.
         */
        ExcelUtil.getSheetList(file)?.map {
            SheetBean(it.sheetNo, it.sheetName)
        }?.apply {
            forEach {
                println("parserExcel sheetBean:${it}")
            }
            //
            inputConfig.sheetNames.addAll(this)
            parserSheet()
        }
    }

    /**
     * 解析 sheet
     * TODO:暂时不对应，后期更改sheet对应module
     */
    private fun parserSheet() {
        if (inputConfig.sheetNames.isNullOrEmpty()) {
            "${inputConfig.excelPath} Excel文件 无Sheet内容!".showError()
        } else if (inputConfig.sheetNames.size == 1) { // 默认选中第一个
            inputConfig.selectSheet = inputConfig.sheetNames.first
            parserData()
        } else { // 用户选择sheet列表界面
            rootBox?.add(createSheetNamesBox())
            rootBox?.revalidate()
        }
    }

    /**
     * 解析 sheet 下的 rows
     */
    private fun parserData() {
        inputConfig.selectSheet?.also {
            val startTime = System.currentTimeMillis()
            ExcelUtil.readRowsBySheetName(inputConfig,
                { rowBean ->

                },
                { errorMsg ->
//                    errorMsg.showError()
                    println("parserData errorMsg:$errorMsg")
                },
                { rows ->
                    inputConfig.rows = rows
                    // 错误提示
                    if (inputConfig.rows.isNullOrEmpty()) {
                        "页码:${inputConfig.selectSheet?.sheetName} 未读取到数据".showError()
                        return@readRowsBySheetName
                    }

                    // 显示语言类型界面列表
                    if (inputConfig.allLangs.isNullOrEmpty()) {
                        "错误：未读取到语言类型".showError()
                    } else {
                        SwingUtilities.invokeLater {
                            val listAllLangs = inputConfig.allLangs!!.map { "$it    ${Constant.langMap[it]}" }
                            rootBox?.add(createLangsBox(listAllLangs))
                            rootBox?.add(createDefValueLang(inputConfig.allLangs!!))
                            showOtherSettings()
                            rootBox?.revalidate()
                        }
                    }

                    // 显示模块列表界面
                    //读取property字段，识别出module有哪些，并与项目中的module取交集
                    var moduleNames:List<String> = rows.groupBy { it.rowAttr?.moduleName }.filter { !it.key.isNullOrEmpty() }.map { it.key ?: "" }

                    // 兼容python脚本 或 没有模块标识的excel文件，将工程的所有模块暴露出来
                    if (moduleNames.isEmpty() && !inputConfig.allModuleBeans.isNullOrEmpty()) {
                        moduleNames = inputConfig.allModuleBeans!!.map { it.moduleName }
                    }

                    SwingUtilities.invokeLater {
                        rootBox?.add(createModulesBox(moduleNames))
                        rootBox?.revalidate()
                    }

                    println("Excel file parser over!")
                    println("Total ${(System.currentTimeMillis() - startTime) / 1000} s")
                }
            )
        }
    }

    private var sheetCombo: JComboBox<String>? = null
    private fun createSheetNamesBox(): Component = Box.createHorizontalBox().also { box ->
        box.add(JLabel("选择Excel页码:").labelSize())
        box.add(Box.createHorizontalGlue())
        sheetCombo = JComboBox<String>()
        sheetCombo?.addItem("请选择")
        inputConfig.sheetNames.forEach {
            sheetCombo?.addItem(it.sheetName)
        }
        box.add(sheetCombo)
    }

    private var langsJCheckBoxList: List<JCheckBox>? = null
    /**
     *  所有语言类型
     */
    private fun createLangsBox(langs: List<String>): JComponent =
        Box.createHorizontalBox().also { parent ->
            parent.add(JLabel("选择需要导入的语言类型:").labelSize())
            parent.add(Box.createHorizontalGlue())
            langsJCheckBoxList = mutableListOf()
            val moduleListView = createCheckBoxListView(langs) { cb, text ->
                //如果excel中的module在项目中找不到则不可选择
                cb.isSelected = true
                langsJCheckBoxList = langsJCheckBoxList?.plus(cb)
            }
            parent.add(moduleListView)
        }

    private var defLangCombo: JComboBox<String>? = null
    private fun createDefValueLang(langs: List<String>): Component? = Box.createHorizontalBox().also { box ->
        box.add(JLabel("选择默认语言语种(默认en-rUS):").labelSize())
        box.add(Box.createHorizontalGlue())
        defLangCombo = JComboBox<String>()
        defLangCombo?.addItem("请选择")
        langs.forEach {
            defLangCombo?.addItem(it)
        }
        box.add(defLangCombo)
    }

    private var moduleJCheckBoxList: List<JCheckBox>? = null
    /**
     * 加入模块列表
     */
    private fun createModulesBox(modules: List<String>): JComponent =
        Box.createHorizontalBox().also { parent ->
            parent.preferredSize = Dimension(200, 100)
            parent.add(JLabel("选择需要导入的模块:").labelSize())
            parent.add(Box.createHorizontalGlue())
            moduleJCheckBoxList = mutableListOf()
            val moduleListView = createCheckBoxListView(modules) { cb, text ->
                //如果excel中的module在项目中找不到则不可选择
                val isExists = inputConfig.allModuleBeans?.find { it.moduleName == text } != null
                cb.isSelected = isExists
                cb.isEnabled = isExists
                moduleJCheckBoxList = moduleJCheckBoxList?.plus(cb)
            }
            parent.add(moduleListView)
        }

    /**
     * 其它的配置
     */
    private fun showOtherSettings() {
        rootBox?.add(Box.createHorizontalBox().also { parent ->
            parent.add(JLabel("是否自动补全缺失的文件夹和文件:").labelSize())
            parent.add(Box.createHorizontalGlue())
            parent.add(JCheckBox("启用/关闭").apply {
                isSelected = true
                addActionListener { inputConfig.isAutoCompletionDirOrFile = isSelected }
            })
        })
//        rootBox?.add(Box.createHorizontalBox().also { parent ->
//            parent.add(JLabel("是否开启智能修复:").labelSize())
//            parent.add(Box.createHorizontalGlue())
//            parent.add(JCheckBox("启用/关闭").apply {
//                isSelected = true
//                addActionListener { inputConfig.isSmartFix = isSelected }
//            })
//        })
        rootBox?.revalidate()
    }

    override fun doOKAction() {
//        super.doOKAction()

        if (inputConfig.rows.isNullOrEmpty()) {
            "重新解析sheet rows".showMessage()
            parserData()
            return
        }

        if (inputConfig.allModuleBeans.isNullOrEmpty()) {
            "${inputConfig.projectName}项目没有发现需要导入的模块!".showWaning()
            return
        }

        //获取用户选择的module
        val selectModules = moduleJCheckBoxList?.filter { it.isSelected }?.map { it.text }
        inputConfig.selectModuleBeans =
            inputConfig.allModuleBeans?.filter { selectModules?.contains(it.moduleName) == true }
        if (inputConfig.allModuleBeans.isNullOrEmpty()) {
            "请先至少选择一个Module!".showWaning()
            return
        }

        // 获取用户选择的语言类型
        inputConfig.selectLangs = langsJCheckBoxList?.filter {
            val index = langsJCheckBoxList?.indexOf(it) ?: -1
            it.isSelected && index >= 0 }?.map {
            val index = langsJCheckBoxList?.indexOf(it) ?: -1
            inputConfig.allLangs?.get(index)!!
        }

        if (inputConfig.selectLangs.isNullOrEmpty()) {
            "请先至少选择一个语言类型!".showWaning()
            return
        }

        // 开始写入xml
        startWrite()
    }

    private fun startWrite() {
        println("=====start write xml file=====start")
        val startTime = System.currentTimeMillis()
        XmlParserUtil.writeRowBeanByXml(inputConfig, {
//            println("startWrite progress $it")
        }, {
            println("startWrite error $it")
        }, {
            "导入${inputConfig.excelPath} 完成，耗时：${(System.currentTimeMillis() - startTime) / 1000}s".showMessage()
        })
        println("=====start write xml file=====end")
    }

}